package me.linczh.framework.persiste;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import me.linczh.bank.bean.AccountBean;
import me.linczh.bank.bean.AccountStatisticBean;
import me.linczh.bank.bean.EmployeeBean;
import me.linczh.bank.bean.LogBean;
import me.linczh.bank.bean.OperatorBean;
import me.linczh.bank.bean.enums.Department;
import me.linczh.bank.bean.enums.Position;

public class FileStoreHolder {
	public static String WEBROOT_PATH;
	private static String ACCOUNT_FILE = "data/account.table";
	private static String OPERATOR_FILE = "data/operator.table";
	private static String EMPLOYEE_FILE = "data/employee.table";
	private static String STATISTIC_FILE = "data/statistic.table";
	private static String LOG_FILE = "data/log.table";
	private static Map<String, AccountBean> accountMap;
	private static List<OperatorBean> operatorList;
	private static Map<String, EmployeeBean> employeeMap;
	private static Map<String, AccountStatisticBean> statisticMap;
	private static List<LogBean> logList;
	
	private FileStoreHolder() {}
	
	public static List<OperatorBean> getOperatorRecords() {
		return operatorList;
	}
	
	public static Map<String, AccountBean> getAccountRecords() {
		return accountMap;
	}
	
	public static Map<String, EmployeeBean> getEmployeeRecords() {
		return employeeMap;
	}
	
	public static Map<String, AccountStatisticBean> getStatisticRecords() {
		return statisticMap;
	}
	
	public static List<LogBean> getLogRecords() {
		return logList;
	}
	
	public static void loadAllRecords() {
		loadAccountRecords();
		loadOperatorRecords();
		loadEmployeeRecords();
		loadStatisticRecords();
		loadLogRecords();
	}
	
	@SuppressWarnings("unchecked")
	public static void loadLogRecords() {
		if (logList == null) {
			logList = new ArrayList<LogBean>();
			ObjectInputStream in = null;
			try {
				in = new ObjectInputStream(new FileInputStream(new File(new URI(WEBROOT_PATH + LOG_FILE))));
				logList = (ArrayList<LogBean>) in.readObject();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void loadStatisticRecords() {
		if (statisticMap == null) {
			statisticMap = new HashMap<String, AccountStatisticBean>();
			ObjectInputStream in = null;
			try {
				in = new ObjectInputStream(new FileInputStream(new File(new URI(WEBROOT_PATH + STATISTIC_FILE))));
				statisticMap = (Map<String, AccountStatisticBean>) in.readObject();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void loadEmployeeRecords() {
		if (employeeMap == null) {
			employeeMap = new HashMap<String, EmployeeBean>();
			ObjectInputStream in = null;
			try {
				in = new ObjectInputStream(new FileInputStream(new File(new URI(WEBROOT_PATH + EMPLOYEE_FILE))));
				employeeMap = (Map<String, EmployeeBean>) in.readObject();
				Integer id = (Integer) in.readObject();
				IdGenerator.initEmployeeId(id);
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void loadOperatorRecords() {
		if (operatorList == null) {
			operatorList = new ArrayList<OperatorBean>();
			ObjectInputStream in = null;
			try {
				in = new ObjectInputStream(new FileInputStream(new File(new URI(WEBROOT_PATH + OPERATOR_FILE))));
				operatorList = (List<OperatorBean>) in.readObject();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void loadAccountRecords() {
		if (accountMap == null) {
			accountMap = new HashMap<String, AccountBean>();
			ObjectInputStream in = null;
			try {
				in = new ObjectInputStream(new FileInputStream(new File(new URI(WEBROOT_PATH + ACCOUNT_FILE))));
				accountMap = (Map<String, AccountBean>) in.readObject();
				Integer id = (Integer) in.readObject();
				IdGenerator.initAccountId(id);
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static void flushLogRecords() {
		if (logList != null) {
			ObjectOutputStream out = null;
			try {
				out = new ObjectOutputStream(new FileOutputStream(new File(new URI(WEBROOT_PATH + LOG_FILE))));
				out.writeObject(logList);
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (out != null) {
					try {
						out.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static void flushStatisticRecords() {
		if (statisticMap != null) {
			ObjectOutputStream out = null;
			try {
				out = new ObjectOutputStream(new FileOutputStream(new File(new URI(WEBROOT_PATH + STATISTIC_FILE))));
				out.writeObject(statisticMap);
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (out != null) {
					try {
						out.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static void flushEmployeeRecords() {
		if (employeeMap != null) {
			ObjectOutputStream out = null;
			try {
				out = new ObjectOutputStream(new FileOutputStream(new File(new URI(WEBROOT_PATH + EMPLOYEE_FILE))));
				out.writeObject(employeeMap);
				out.writeObject(IdGenerator.getEmployeeId());
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (out != null) {
					try {
						out.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static void flushOperatorRecords() {
		if (operatorList != null) {
			ObjectOutputStream out = null;
			try {
				out = new ObjectOutputStream(new FileOutputStream(new File(new URI(WEBROOT_PATH + OPERATOR_FILE))));
				out.writeObject(operatorList);
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (out != null) {
					try {
						out.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static void flushAccountRecords() {
		if (accountMap != null) {
			ObjectOutputStream out = null;
			try {
				out = new ObjectOutputStream(new FileOutputStream(new File(new URI(WEBROOT_PATH + ACCOUNT_FILE))));
				out.writeObject(accountMap);
				out.writeObject(IdGenerator.getAccountId());
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (out != null) {
					try {
						out.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static void init() {
		
		accountMap = new HashMap<String, AccountBean>();
		IdGenerator.initAccountId(1000);
		flushAccountRecords();
		
		statisticMap = new HashMap<String, AccountStatisticBean>();
		flushStatisticRecords();
		
		employeeMap = new HashMap<String, EmployeeBean>();
		EmployeeBean ebean0 = new EmployeeBean();
		ebean0.setUsername("admin");
		ebean0.setPassword("1234");
		ebean0.setDepartment(Department.DEPART3);
		ebean0.setEmployee("3-20131211-1000");
		ebean0.setPosition(Position.ADMIN);
		
		EmployeeBean ebean1 = new EmployeeBean();
		ebean1.setUsername("linczh");
		ebean1.setPassword("1234");
		ebean1.setDepartment(Department.DEPART1);
		ebean1.setEmployee("0-20131211-1001");
		ebean1.setPosition(Position.OPERATOR);
		
		EmployeeBean ebean2 = new EmployeeBean();
		ebean2.setUsername("manager");
		ebean2.setPassword("1234");
		ebean2.setDepartment(Department.DEPART1);
		ebean2.setEmployee("1-20131211-1002");
		ebean2.setPosition(Position.MANAGER);
		
		EmployeeBean ebean3 = new EmployeeBean();
		ebean3.setUsername("supervisor");
		ebean3.setPassword("1234");
		ebean3.setDepartment(Department.DEPART1);
		ebean3.setEmployee("2-20131211-1003");
		ebean3.setPosition(Position.SUPERVISOR);
		
		employeeMap.put(ebean0.getEmployee(), ebean0);
		employeeMap.put(ebean1.getEmployee(), ebean1);
		employeeMap.put(ebean2.getEmployee(), ebean2);
		employeeMap.put(ebean3.getEmployee(), ebean3);
		
		IdGenerator.initEmployeeId(1005);
		flushEmployeeRecords();
		
		logList = new ArrayList<LogBean>();
		flushLogRecords();
		
		operatorList = new ArrayList<OperatorBean>();
		flushOperatorRecords();
	}
}
